package com.fuhao.gatewayservice.filter;

import com.google.common.util.concurrent.RateLimiter;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;

import static org.springframework.cloud.netflix.zuul.filters.support.FilterConstants.PRE_TYPE;

/**
 * 限流过滤器
 */

@Component
public class ReLimiterFilter extends ZuulFilter {

    //获取令牌桶，每秒产生1000个令牌
    private static final RateLimiter RATE_LIMITER = RateLimiter.create(1000);

    @Override
    public String filterType() {
        return PRE_TYPE;
    }

    /**
     * 在所有过滤器中最先执行
     * @return
     */
    @Override
    public int filterOrder() {
        return -4;
    }

    /**
     * 对订单接口限流
     * @return
     */
    @Override
    public boolean shouldFilter() {
        //获取上下文对象
        RequestContext context = RequestContext.getCurrentContext();
        HttpServletRequest request = context.getRequest();

        //此处是写死的，可以写到数据库，每次启动服务，拉去服务列表，然后判断。可以使用ACL
        if("/apigateway/order/api/v1/order/save".equalsIgnoreCase(request.getRequestURI())){
            return true;
        }
        return false;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext context = RequestContext.getCurrentContext();
       //获取限流令牌
        if(!RATE_LIMITER.tryAcquire()){
            //表示没有拿到令牌
            context.setSendZuulResponse(false);
            context.setResponseStatusCode(HttpStatus.TOO_MANY_REQUESTS.value());//429表示太多人请求
            System.out.println("太多人了");
       }
        return null;
    }
}
